<template>
	<picker-view :indicator-style="indicatorStyle" :value="innerValue" @change="handleChange" class="picker-view">
		<picker-view-column v-for="col in columns" :key="col.type">
			<view class="item" v-for="item in col.values" :key="item">{{item}}{{col.label}}</view>
		</picker-view-column>
	</picker-view>
</template>


<script>
	import dayjs from 'dayjs'
	export default {
		props: {
			value: {
				type: String,
				default: ''
			},
			// 前10 
			minDate: {
				type: String,
				default: () => dayjs().subtract(10, 'y').format('YYYY-MM-DD')
			},
			// 后10 
			maxDate: {
				type: String,
				default: () => dayjs().add(10, 'y').format('YYYY-MM-DD')
			},
		},
		data() {
			return {
				innerValue: [],
				indicatorStyle: 'height: 50px;',
				columns: [],
				currentDate: ''
			}
		},
		methods: {
			getMaxMinDate(type) {
				const boundary = new Date(this[`${type}Date`])
				let year = dayjs(boundary).year()
				let month = dayjs(boundary).month() + 1
				let date = dayjs(boundary).date()
				return [year, month, date]
				// let hour = dayjs(boundary).hour()
				// let minute = dayjs(boundary).minute()
				// return [year, month, date, hour, minute]
			},
			getCurrentDate(indexs) {
				let values = []
				indexs.map((val, index) => {
					values[index] = parseInt(this.columns[index].values[val] || 0)
				})
				const minDateValues = this.getMaxMinDate('min')
				const maxDateValues = this.getMaxMinDate('max')
				// 最小值 minDateValues
				if (values[0] === minDateValues[0]) {
					values.forEach((item, iIndex) => {
						if (iIndex > 0 && item < minDateValues[iIndex]) {
							values[iIndex] = minDateValues[iIndex]
						}
					})
				} else if (values[0] === maxDateValues[0]) {
					values.forEach((item, iIndex) => {
						if (iIndex > 0 && item > maxDateValues[iIndex]) {
							values[iIndex] = maxDateValues[iIndex]
						}
					})
				}

				const daysInMonth = dayjs(`${values[0]}-${values[1]}`).daysInMonth()
				if (values[2] > daysInMonth) {
					values[2] = daysInMonth
				}
				return values
			},
			async handleChange(e) {
				const currentValues = this.getCurrentDate(e.detail.value)
				let currentDate =
					`${currentValues[0]}-${currentValues[1]}-${currentValues[2]}`
				if (!dayjs(currentDate).isValid()) return
				this.currentDate = dayjs(currentDate).format('YYYY-MM-DD')
				this.$emit("change", this.currentDate)
				this.updateColumns()
				await uni.$u.sleep(100)
				this.updateValue()
			},
			/**
			 * 初始化组件
			 */
			async init(val) {
				if (!val) {
					val = new Date()
				}
				this.currentDate = dayjs(val).format('YYYY-MM-DD')
				this.updateColumns()
				await uni.$u.sleep(100)
				this.updateValue()
			},
			updateValue() {
				const padZero = uni.$u.padZero
				const dateVal = this.currentDate ? new Date(this.currentDate) : new Date()
				const year = `${dayjs(dateVal).year()}`
				const month = padZero(dayjs(dateVal).month() + 1)
				const date = padZero(dayjs(dateVal).date())
				const values = [year, month, date]
				// const hour = padZero(dayjs(dateVal).hour())
				// const minute = padZero(dayjs(dateVal).minute())
				// const values = [year, month, date, hour, minute]
				const indexs = this.columns.map((column, index) => {
					// 通过取大值，可以保证不会出现找不到索引的-1情况
					return Math.max(0, column.values.findIndex(item => item === values[index]))
				})
				this.innerValue = indexs
			},
			updateColumns() {
				const results = this.getOriginColumns()
				this.columns = results
			},
			getOriginColumns() {
				const results = this.getRanges().map(({
					type,
					label,
					range
				}) => {
					let values = this.times(range[1] - range[0] + 1, (index) => {
						let value = range[0] + index
						// 获取各列的值，对各列的具体值进行补0操作
						value = type === 'year' ? `${value}` : uni.$u.padZero(value)
						return value
					})
					return {
						type,
						label,
						values
					}
				})
				return results
			},
			// 设置列数据
			times(n, iteratee) {
				let index = -1
				const result = new Array(n < 0 ? 0 : n)
				while (++index < n) {
					result[index] = iteratee(index)
				}
				return result
			},
			getRanges() {
				const {
					maxYear,
					maxDate,
					maxMonth,
					// maxHour,
					// maxMinute,
				} = this.getBoundary('max');
				const {
					minYear,
					minDate,
					minMonth,
					// minHour,
					// minMinute,
				} = this.getBoundary('min');

				let result = [{
						type: 'year',
						label: '年',
						range: [minYear, maxYear],
					},
					{
						type: 'month',
						label: '月',
						range: [minMonth, maxMonth],
					},
					{
						type: 'day',
						label: '日',
						range: [minDate, maxDate],
					},
					// {
					// 	type: 'hour',
					// 	label: '时',
					// 	range: [minHour, maxHour],
					// },
					// {
					// 	type: 'minute',
					// 	label: '分',
					// 	range: [minMinute, maxMinute],
					// },
				]
				return result;
			},
			/**
			 * 获取界限
			 * type:min max
			 */
			getBoundary(type) {
				const value = this.currentDate
				const boundary = new Date(this[`${type}Date`])
				const year = dayjs(boundary).year()
				let month = 1
				let date = 1
				// let hour = 0
				// let minute = 0
				if (type === 'max') {
					month = 12
					date = dayjs(value).daysInMonth() // 月份的天数
					// hour = 23
					// minute = 59
				}
				// 获取边界值，逻辑是：当年达到了边界值(最大或最小年)，就检查月允许的最大和最小值，以此类推
				if (dayjs(value).year() === year) {
					month = dayjs(boundary).month() + 1
					if (dayjs(value).month() + 1 === month) {
						date = dayjs(boundary).date()
						// if (dayjs(value).date() === date) {
						// 	hour = dayjs(boundary).hour()
						// 	if (dayjs(value).hour() === hour) {
						// 		minute = dayjs(boundary).minute()
						// 	}
						// }
					}
				}
				return {
					[`${type}Year`]: year,
					[`${type}Month`]: month,
					[`${type}Date`]: date,
					// [`${type}Hour`]: hour,
					// [`${type}Minute`]: minute
				}
			},
		}
	}
</script>

<style lang="scss" scoped>
	.picker-view {
		width: 100vw;
		height: 500rpx;
		margin-top: 20rpx;
	}

	.item {
		line-height: 100rpx;
		text-align: center;
	}
</style>